TPL_SIGNAL_ID_HEADER = \
    """/* Copyright ©, 2022, ECARX (Hubei) Technology Co., Ltd. All rights reserved.
 *
 * NOTICE: This file contains information which is confidential and proprietary to ECARX
 * (Hubei) Technology Co., Ltd. and/or other developers. No license to any intellectual
 * property rights contained within this file is either granted or implied except as may be
 * provided in an agreement with ECARX (Hubei) Technology Co., Ltd.
 *
 * Any unauthorized copying or distribution of content from this file in whole or in part
 * is prohibited.
 */
/**
 * ****************************************
 * NOTE : DO NOT EDIT THIS FILE
 *        AUTO GEN BY PYTHON SCRIPT 
 * ****************************************
 */
#pragma once

#include <cstdint>
#include "transfer/common.h"

namespace ecarx::transfer {

    enum class APCPSignalTX : int32_t {

"""

TPL_SIGNAL_TX_RX_DIVIDER = \
    """
    };

    enum class APCPSignalRX : int32_t {

"""

TPL_SIGNAL_ENUMS_DIVIDER = \
    """
    };

    namespace sdb {
"""

TPL_SIGNAL_FOOT = \
    """
    }

}
"""

TPL_SIGNAL_ID = \
    """
        /*********************************************
         * note         : _NOTE
         * encodeType   : _ENCODE_TYPE
         * Swrs Name    : _SWRS_NAME
         * value        : _SIGNAL_VALVE_STRING
         * ********************************************
         */
         _SIGNAL_NAME = _SIGNAL_VALUE_HEX,
"""


TPL_ENUM = \
    """
        enum class ENUM_NAME : int32_t {

ENUM_MEMBER

        };
"""

TPL_PRAGMA = \
    """#pragma once
"""

TPL_OPCODE = \
    """#define _SIGNALOpId _VALUE
"""

TPL_STRUCT_TX = \
    """
#pragma pack(1)
typedef struct _Op_SIGNAL_SetRequestNoReturn {
    _PAYLOAD_t _VALUE;
} Op_SIGNAL_SetRequestNoReturn;
#pragma pack()
"""

TPL_STRUCT_RX = \
    """
#pragma pack(1)
typedef struct _Op_SIGNAL_Notify {
    _PAYLOAD_t _VALUE;
} Op_SIGNAL_Notify;
#pragma pack()
"""

TPL_APCP_TRANSFER_HEADER = \
    """#pragma once
    
    #include <vector>
    #include <memory>
    #include <functional>
    #include <transfer/ITransfer.h>
    #include "cp/CP_ServiceId.h"
    
    namespace ecarx::transfer::apcp {
    
        class APCPConn:public ITransfer{
            class NetAPCP;
            NetAPCP* mImpl;
            public:
            explicit APCPConn();
            ~APCPConn();
            //打开链接
            bool open() override;
            //关闭链接
            bool close() override;
            //将数据写到网络上
            bool write(const Signal &) override;
            const std::optional<Signal> read(const int32_t signalId) const override;
            NetState getState() override;
            void onSignalChanged(SignalChangeCallback && callback) override;
            void registerStateHandler(NetStateCallback && callback) override;
        

        };
    
        struct ValidOperationArray {
            int len;
            uint16_t *oper_ids;
        };
    
        static uint16_t CPNormalOps[] = {NORMAL_OP_IDS};
        static uint16_t CPTimeSyncOps[] = {TIMESYNC_OP_IDS};
        static uint16_t CPAVASOps[] = {AVAS_OP_IDS};
        static uint16_t CPHostInfoOps[] = {HOSTINFO_OP_IDS};
        static uint16_t CPPowerOps[] = {POWER_OP_IDS};
    
        ValidOperationArray getValidOperationArray(uint16_t serviceId) {
            switch (serviceId) {
                case CP_serviceID_Normal:
                    return ValidOperationArray{
                            .len = NORMAL_OP_NUM,
                            .oper_ids = CPNormalOps,
                    };
                case CP_serviceID_TimeSync:
                    return ValidOperationArray{
                            .len = TIMESYNC_OP_NUM,
                            .oper_ids = CPTimeSyncOps,
                    };
                case CP_serviceID_AVAS:
                    return ValidOperationArray{
                            .len = AVAS_OP_NUM,
                            .oper_ids = CPAVASOps,
                    };
                case CP_serviceID_HostInfo:
                    return ValidOperationArray{
                            .len = HOSTINFO_OP_NUM,
                            .oper_ids = CPHostInfoOps,
                    };
                case CP_serviceID_Power:
                    return ValidOperationArray{
                            .len = POWER_OP_NUM,
                            .oper_ids = CPPowerOps,
                    };
                default:
                    return ValidOperationArray{};
            }
        }
    
        const uint16_t getReadyServiceIds[] = {
                CP_serviceID_Normal,
                CP_serviceID_TimeSync,
                CP_serviceID_AVAS,
                CP_serviceID_HostInfo,
                CP_serviceID_Power,
        };
    
    }
    """

TPL_SIGNAL_H_FRONT = \
    """/* Copyright ©, 2022, ECARX (Hubei) Technology Co., Ltd. All rights reserved.
 *
 * NOTICE: This file contains information which is confidential and proprietary to ECARX
 * (Hubei) Technology Co., Ltd. and/or other developers. No license to any intellectual
 * property rights contained within this file is either granted or implied except as may be
 * provided in an agreement with ECARX (Hubei) Technology Co., Ltd.
 *
 * Any unauthorized copying or distribution of content from this file in whole or in part
 * is prohibited.
 */
/**
 * ****************************************
 * NOTE : DO NOT EDIT THIS FILE
 *        AUTO GEN BY PYTHON SCRIPT 
 * ****************************************
 */
#pragma once

#include <cstdint>
#include <array>
#include <string>
#include <memory>
#include <transfer/ITransfer.h>

#include "ap/APCP_signal_id.h"

#include "cp/Normal.h"
#include "cp/TimeSync.h"
#include "cp/AVAS.h"
#include "cp/HostInfo.h"
#include "cp/Power.h"

"""

TPL_SIGNAL_H_BODY = \
    """
namespace ecarx::transfer {

    class APCPSignalManager {
    protected:
        std::shared_ptr<ITransfer> mAPCPConn;
    public:
        APCPSignalManager(std::shared_ptr<ITransfer> conn) : mAPCPConn(conn) {

        }

        bool isAPCPReady() const;

"""

TPL_SIGNAL_H_SET_FUNC = \
    """        /**
        * FUNCTION_NOTE
        * @param value VALUE_NOTE
        */
        void setSIGNAL_NAME(PAYLOAD_NAME SHOW_VALUE) const;

"""

TPL_SIGNAL_H_GET_FUNC = \
    """        /**
        * FUNCTION_NOTE
        * @param value VALUE_NOTE
        */
        PAYLOAD_NAME getSIGNAL_NAME() const;

"""

TPL_SIGNAL_H_END = \
    """
       };
    
    }
    """

TPL_SIGNAL_CPP_FRONT = \
    """#include "ap/APCPSignalManager.h"
#include <transfer/utils.h>

namespace ecarx::transfer {

    bool APCPSignalManager::isAPCPReady() const {
        if (mAPCPConn != nullptr) {
            return mAPCPConn->getState() == NetState::Ready;
        }
        return false;
    }
"""

TPL_SIGNAL_CPP_FUNC_SET_INT = \
    """
    void APCPSignalManager::setSIGNAL_NAME(PAYLOAD_NAME SHOW_VALUE) const {
        Signal signal;
        signal.signalId = (int32_t)APCPSignalTX::SIGNAL_NAME;
        signal.value.int32Values = {(int32_t) SHOW_VALUE};
        if (mAPCPConn != nullptr) {
            mAPCPConn->write(signal);
        }
    }
"""

TPL_SIGNAL_CPP_FUNC_SET_BYTE = \
    """
    void APCPSignalManager::setSIGNAL_NAME(PAYLOAD_NAME SHOW_VALUE) const {
        Signal signal;
        signal.signalId = (int32_t)APCPSignalTX::SIGNAL_NAME;
        auto bytes = utils::toBytes(SHOW_VALUE);
        signal.value.bytes = (std::vector<uint8_t>) bytes;
        if (mAPCPConn != nullptr) {
            mAPCPConn->write(signal);
        }
    }
"""

TPL_SIGNAL_CPP_FUNC_SET_BYTE_VEC = \
    """
    void APCPSignalManager::setSIGNAL_NAME(PAYLOAD_NAME SHOW_VALUE) const {
        Signal signal;
        signal.signalId = (int32_t)APCPSignalTX::SIGNAL_NAME;
        signal.value.bytes = SHOW_VALUE;
        if (mAPCPConn != nullptr) {
            mAPCPConn->write(signal);
        }
    }
"""

TPL_SIGNAL_CPP_FUNC_GET_INT = \
    """
    PAYLOAD_NAME APCPSignalManager::getSIGNAL_NAME() const {
        std::optional<Signal> signal;
        if (mAPCPConn != nullptr) {
            signal = mAPCPConn->read((int32_t)APCPSignalRX::SIGNAL_NAME);
        }
        if (signal.has_value()) {
            return static_cast<PAYLOAD_NAME>(signal->value.int32Values[0]);
        }
        return -1;
    }
"""

TPL_SIGNAL_CPP_FUNC_GET_ENUM = \
    """
    PAYLOAD_NAME APCPSignalManager::getSIGNAL_NAME() const {
        std::optional<Signal> signal;
        if (mAPCPConn != nullptr) {
            signal = mAPCPConn->read((int32_t)APCPSignalRX::SIGNAL_NAME);
        }
        if (signal.has_value()) {
            return PAYLOAD_NAME(signal->value.int32Values[0]);
        }
        return PAYLOAD_NAME(-1);
    }
"""

TPL_SIGNAL_CPP_FUNC_GET_BYTES = \
    """
    PAYLOAD_NAME APCPSignalManager::getSIGNAL_NAME() const {
        std::optional<Signal> signal;
        if (mAPCPConn != nullptr) {
            signal = mAPCPConn->read((int32_t)APCPSignalRX::SIGNAL_NAME);
        }
        if (signal.has_value()) {
            return utils::toValue<SIGNAL_NAME>(signal->value.bytes);
        }
        return SIGNAL_NAME{};
    }
"""

TPL_SIGNAL_CPP_END = \
    """
}
"""

TPL_TO_IPCP_FRONT = \
    """/* Copyright ©, 2023, ECARX (Hubei) Technology Co., Ltd. All rights reserved.
 *
 * NOTICE: This file contains information which is confidential and proprietary to ECARX
 * (Hubei) Technology Co., Ltd. and/or other developers. No license to any intellectual
 * property rights contained within this file is either granted or implied except as may be
 * provided in an agreement with ECARX (Hubei) Technology Co., Ltd.
 *
 * Any unauthorized copying or distribution of content from this file in whole or in part
 * is prohibited.
 */
#pragma once

#include <vector>
#include <transfer/common.h>
#include <arpa/inet.h>
#include <map>
#include <ipcp/ipcp.h>
#include <functional>

#include "ap/APCP_signal_id.h"
#include "common.h"
#include "cp/CP_ServiceId.h"
#include "cp/Normal.h"
#include "cp/AVAS.h"
#include "cp/TimeSync.h"

namespace ecarx::transfer::utils {

    ipcp::IpcpValue cpSignalToIpcpValue(const Signal &signal) {
        ipcp::IpcpValue ipcp;
        ipcp.service_id = CP_serviceID_Invalid;
        // CP_serviceID_Invalid
        if (signal.signalId == CP_serviceID_Invalid) {
            return ipcp;
        }/**/
"""

TPL_TO_IPCP_END = \
    """        return ipcp;
    }
}
"""

TPL_TO_IPCP_INT32 = \
    """        else if (signal.signalId == (int32_t)APCPSignalTX::SIGNAL_NAME) {
            ipcp.service_id = SERVICE_ID;
            ipcp.oper_id = OP_ID;
            ipcp.oper_type = IPCP_OPERATION_SETREQUEST_NORETURN;
            ipcp.payload_type = IPCP_DATA_NORMAL;
            memset(ipcp.peer_ip, 0, sizeof(ipcp.peer_ip));
            strcpy(ipcp.peer_ip, CP_SERVICE_IP);
            ipcp.peer_port = SERVICE_PORT;
            ipcp.payload_len = sizeof(OpSIGNAL_NAME_SetRequestNoReturn);
            OpSIGNAL_NAME_SetRequestNoReturn *buffer =
                    (OpSIGNAL_NAME_SetRequestNoReturn *) new uint8_t[ipcp.payload_len];
            (*buffer).value = (uint8_t) signal.value.int32Values[0];
            ipcp.payload = (void *) buffer;
        }/**/
"""
TPL_TO_IPCP_BYTES = \
    """        else if (signal.signalId == (int32_t)APCPSignalTX::SIGNAL_NAME) {
            ipcp.service_id = SERVICE_ID;
            ipcp.oper_id = OP_ID;
            ipcp.oper_type = IPCP_OPERATION_SETREQUEST_NORETURN;
            ipcp.payload_type = IPCP_DATA_NORMAL;
            memset(ipcp.peer_ip, 0, sizeof(ipcp.peer_ip));
            strcpy(ipcp.peer_ip, CP_SERVICE_IP);
            ipcp.peer_port = SERVICE_PORT;
            ipcp.payload_len = sizeof(OpSIGNAL_NAME_SetRequestNoReturn);
            OpSIGNAL_NAME_SetRequestNoReturn set;
            memcpy(&set, signal.value.bytes.data(), signal.value.bytes.size());
            OpSIGNAL_NAME_SetRequestNoReturn *buffer =
                    (OpSIGNAL_NAME_SetRequestNoReturn *)
                            new uint8_t[ipcp.payload_len];
            memcpy(buffer, &set, ipcp.payload_len);
            ipcp.payload = (void *) buffer;
        }
"""
TPL_TO_IPCP_VEC_BYTES = \
    """        else if (signal.signalId == (int32_t)APCPSignalTX::SIGNAL_NAME) {
            ipcp.service_id = SERVICE_ID;
            ipcp.oper_id = OP_ID;
            ipcp.oper_type = IPCP_OPERATION_SETREQUEST_NORETURN;
            ipcp.payload_type = IPCP_DATA_NORMAL;
            memset(ipcp.peer_ip, 0, sizeof(ipcp.peer_ip));
            strcpy(ipcp.peer_ip, CP_SERVICE_IP);
            ipcp.peer_port = SERVICE_PORT;
            ipcp.payload_len = signal.value.bytes.size();
            ipcp.payload = (void *) signal.value.bytes.data();
        }
"""
TPL_TO_SIGNAL_BYTE = \
    """        else if(ipcpValue.service_id == SERVICE_ID
                && ipcpValue.oper_id == OP_ID) {
            constexpr int structLen = (int) sizeof(OpSIGNAL_NAME_Notify);
            int bufferLength = structLen;
            if (ipcpValue.payload_len < structLen) {
                bufferLength = ipcpValue.payload_len;
            }
            signals.reserve(1);
            OpSIGNAL_NAME_Notify data;
            memcpy(&data, ipcpValue.payload, bufferLength);
            Signal signal;
            signal.signalId = (int32_t)APCPSignalRX::SIGNAL_NAME;
            signal.value.bytes.resize(sizeof(OpSIGNAL_NAME_Notify), 0);
            memcpy(signal.value.bytes.data(), &data, sizeof(OpSIGNAL_NAME_Notify));
            signals.emplace_back(signal);
        }      
"""
TPL_TO_SIGNAL_BYTE_PULL = \
    """        else if(ipcpValue.service_id == SERVICE_ID
                && ipcpValue.oper_id == OP_ID) {
            OpSIGNAL_NAME_Notify signal;
            int bufferLength = (int) sizeof(OpSIGNAL_NAME_Notify);
            if (ipcpValue.payload_len < bufferLength) {
            bufferLength = ipcpValue.payload_len;
            }
            signals.reserve(MEMBER_SIZE);
            memcpy(&signal, ipcpValue.payload, bufferLength);
EMPLACE_CONTENT
        }
"""
TPL_TO_SIGNAL_INT32 = \
    """        else if(ipcpValue.service_id == SERVICE_ID
                && ipcpValue.oper_id == OP_ID) {
            OpSIGNAL_NAME_Notify signal;
            int bufferLength = (int) sizeof(OpSIGNAL_NAME_Notify);
            if (ipcpValue.payload_len < bufferLength) {
                bufferLength = ipcpValue.payload_len;
            }
            signals.reserve(1);
            memcpy(&signal, ipcpValue.payload, bufferLength);
            signals.emplace_back(Signal{
                    .signalId=(int32_t)APCPSignalRX::SIGNAL_NAME,
                    .value.int32Values = {(int32_t)signal.value}
            });
        }
"""
TPL_TO_SIGNAL_EMPLACE = \
    """            signals.emplace_back(Signal{
                    .signalId=(int32_t)APCPSignalRX::MEMBER_NAME,
                    .value.int32Values = {signal.mMEMBER_NAME}
            });
"""

TPL_TO_SIGNAL_FRONT = \
    """/* Copyright ©, 2023, ECARX (Hubei) Technology Co., Ltd. All rights reserved.
 *
 * NOTICE: This file contains information which is confidential and proprietary to ECARX
 * (Hubei) Technology Co., Ltd. and/or other developers. No license to any intellectual
 * property rights contained within this file is either granted or implied except as may be
 * provided in an agreement with ECARX (Hubei) Technology Co., Ltd.
 *
 * Any unauthorized copying or distribution of content from this file in whole or in part
 * is prohibited.
 */
#pragma once

#include <vector>
#include <transfer/common.h>
#include <arpa/inet.h>
#include <map>
#include <ipcp/ipcp.h>
#include <functional>

#include "ap/APCP_signal_id.h"
#include "common.h"
#include "cp/CP_ServiceId.h"
#include "cp/Normal.h"
#include "cp/AVAS.h"
#include "cp/TimeSync.h"
#include "cp/HostInfo.h"
#include "cp/Power.h"
    
namespace ecarx::transfer::utils {
    
    std::vector<Signal> cpIpcpValueToSignal(const ipcp::IpcpValue &ipcpValue){
        std::vector<Signal> signals = {};
        // CP_serviceID_Invalid
        if (ipcpValue.service_id == CP_serviceID_Invalid) {
            return signals;
        }/**/
"""

TPL_TO_SIGNAL_END = \
    """        return signals;
    }
}
"""
